home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 14 / CU Amiga Magazine's Super CD-ROM 14 (1997)(EMAP Images)(GB)(Track 1 of 3)[!][issue 1997-09].iso / CUCD / Programming / Mesa-2.2 / src / teximage.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-03-13  |  66.4 KB  |  2,117 lines

  1. /* $Id: teximage.c,v 1.14 1997/03/04 19:18:29 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  2.2
  6.  * Copyright (C) 1995-1997  Brian Paul
  7.  *
  8.  * This library is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU Library General Public
  10.  * License as published by the Free Software Foundation; either
  11.  * version 2 of the License, or (at your option) any later version.
  12.  *
  13.  * This library is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.  * Library General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU Library General Public
  19.  * License along with this library; if not, write to the Free
  20.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  */
  22.  
  23.  
  24. /*
  25.  * $Log: teximage.c,v $
  26.  * Revision 1.14  1997/03/04 19:18:29  brianp
  27.  * added texture image Width2, Height2, and Depth2 fields
  28.  *
  29.  * Revision 1.13  1997/02/27 19:58:08  brianp
  30.  * call gl_problem() instead of gl_warning()
  31.  *
  32.  * Revision 1.12  1997/02/09 18:53:05  brianp
  33.  * added GL_EXT_texture3D support
  34.  *
  35.  * Revision 1.11  1997/01/16 03:35:10  brianp
  36.  * added calls to device driver TexImage() function
  37.  *
  38.  * Revision 1.10  1997/01/09 21:26:46  brianp
  39.  * gl_TexImage[12]D() didn't free the incoming image- a memory leak
  40.  *
  41.  * Revision 1.9  1997/01/09 19:55:52  brianp
  42.  * fixed a few error messages
  43.  *
  44.  * Revision 1.8  1997/01/09 19:49:18  brianp
  45.  * better error checking
  46.  *
  47.  * Revision 1.7  1996/12/02 18:59:54  brianp
  48.  * added code to handle GL_COLOR_INDEX textures, per Randy Frank
  49.  *
  50.  * Revision 1.6  1996/11/07 04:13:24  brianp
  51.  * all new texture image handling, now pixel scale, bias, mapping work
  52.  *
  53.  * Revision 1.5  1996/09/27 01:29:57  brianp
  54.  * removed unused variables, fixed cut&paste bug in color scaling
  55.  *
  56.  * Revision 1.4  1996/09/26 22:35:10  brianp
  57.  * fixed a few compiler warnings from IRIX 6 -n32 and -64 compiler
  58.  *
  59.  * Revision 1.3  1996/09/15 14:18:55  brianp
  60.  * now use GLframebuffer and GLvisual
  61.  *
  62.  * Revision 1.2  1996/09/15 01:48:58  brianp
  63.  * removed #define NULL 0
  64.  *
  65.  * Revision 1.1  1996/09/13 01:38:16  brianp
  66.  * Initial revision
  67.  *
  68.  */
  69.  
  70.  
  71. #include <assert.h>
  72. #include <stdlib.h>
  73. #include <string.h>
  74. #include "context.h"
  75. #include "image.h"
  76. #include "macros.h"
  77. #include "pixel.h"
  78. #include "span.h"
  79. #include "teximage.h"
  80. #include "types.h"
  81.  
  82.  
  83.  
  84. /*
  85.  * NOTES:
  86.  *
  87.  * The internal texture storage convension is an array of N GLubytes
  88.  * where N = width * height * components.  There is no padding.
  89.  */
  90.  
  91.  
  92.  
  93.  
  94. /*
  95.  * Compute log base 2 of n.
  96.  * If n isn't an exact power of two return -1.
  97.  * If n<0 return -1.
  98.  */
  99. static int logbase2( int n )
  100. {
  101.    GLint i = 1;
  102.    GLint log2 = 0;
  103.  
  104.    if (n<0) {
  105.       return -1;
  106.    }
  107.  
  108.    while ( n > i ) {
  109.       i *= 2;
  110.       log2++;
  111.    }
  112.    if (i != n) {
  113.       return -1;
  114.    }
  115.    else {
  116.       return log2;
  117.    }
  118. }
  119.  
  120.  
  121.  
  122. /*
  123.  * Given an internal texture format enum or 1, 2, 3, 4 return the
  124.  * corresponding _base_ internal format:  GL_ALPHA, GL_LUMINANCE,
  125.  * GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, or GL_RGBA.  Return -1 if
  126.  * invalid enum.
  127.  */
  128. static GLint decode_internal_format( GLint format )
  129. {
  130.    switch (format) {
  131.       case GL_ALPHA:
  132.       case GL_ALPHA4:
  133.       case GL_ALPHA8:
  134.       case GL_ALPHA12:
  135.       case GL_ALPHA16:
  136.          return GL_ALPHA;
  137.       case 1:
  138.       case GL_LUMINANCE:
  139.       case GL_LUMINANCE4:
  140.       case GL_LUMINANCE8:
  141.       case GL_LUMINANCE12:
  142.       case GL_LUMINANCE16:
  143.          return GL_LUMINANCE;
  144.       case 2:
  145.       case GL_LUMINANCE_ALPHA:
  146.       case GL_LUMINANCE4_ALPHA4:
  147.       case GL_LUMINANCE6_ALPHA2:
  148.       case GL_LUMINANCE8_ALPHA8:
  149.       case GL_LUMINANCE12_ALPHA4:
  150.       case GL_LUMINANCE12_ALPHA12:
  151.       case GL_LUMINANCE16_ALPHA16:
  152.          return GL_LUMINANCE_ALPHA;
  153.       case GL_INTENSITY:
  154.       case GL_INTENSITY4:
  155.       case GL_INTENSITY8:
  156.       case GL_INTENSITY12:
  157.       case GL_INTENSITY16:
  158.          return GL_INTENSITY;
  159.       case 3:
  160.       case GL_RGB:
  161.       case GL_R3_G3_B2:
  162.       case GL_RGB4:
  163.       case GL_RGB5:
  164.       case GL_RGB8:
  165.       case GL_RGB10:
  166.       case GL_RGB12:
  167.       case GL_RGB16:
  168.          return GL_RGB;
  169.       case 4:
  170.       case GL_RGBA:
  171.       case GL_RGBA2:
  172.       case GL_RGBA4:
  173.       case GL_RGB5_A1:
  174.       case GL_RGBA8:
  175.       case GL_RGB10_A2:
  176.       case GL_RGBA12:
  177.       case GL_RGBA16:
  178.          return GL_RGBA;
  179.       default:
  180.          return -1;  /* error */
  181.    }
  182. }
  183.  
  184.  
  185.  
  186. /*
  187.  * Given an internal texture format enum or 1, 2, 3, 4 return the
  188.  * corresponding _base_ internal format:  GL_ALPHA, GL_LUMINANCE,
  189.  * GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, or GL_RGBA.  Return the
  190.  * number of components for the format.  Return -1 if invalid enum.
  191.  */
  192. static GLint components_in_intformat( GLint format )
  193. {
  194.    switch (format) {
  195.       case GL_ALPHA:
  196.       case GL_ALPHA4:
  197.       case GL_ALPHA8:
  198.       case GL_ALPHA12:
  199.       case GL_ALPHA16:
  200.          return 1;
  201.       case 1:
  202.       case GL_LUMINANCE:
  203.       case GL_LUMINANCE4:
  204.       case GL_LUMINANCE8:
  205.       case GL_LUMINANCE12:
  206.       case GL_LUMINANCE16:
  207.          return 1;
  208.       case 2:
  209.       case GL_LUMINANCE_ALPHA:
  210.       case GL_LUMINANCE4_ALPHA4:
  211.       case GL_LUMINANCE6_ALPHA2:
  212.       case GL_LUMINANCE8_ALPHA8:
  213.       case GL_LUMINANCE12_ALPHA4:
  214.       case GL_LUMINANCE12_ALPHA12:
  215.       case GL_LUMINANCE16_ALPHA16:
  216.          return 2;
  217.       case GL_INTENSITY:
  218.       case GL_INTENSITY4:
  219.       case GL_INTENSITY8:
  220.       case GL_INTENSITY12:
  221.       case GL_INTENSITY16:
  222.          return 1;
  223.       case 3:
  224.       case GL_RGB:
  225.       case GL_R3_G3_B2:
  226.       case GL_RGB4:
  227.       case GL_RGB5:
  228.       case GL_RGB8:
  229.       case GL_RGB10:
  230.       case GL_RGB12:
  231.       case GL_RGB16:
  232.          return 3;
  233.       case 4:
  234.       case GL_RGBA:
  235.       case GL_RGBA2:
  236.       case GL_RGBA4:
  237.       case GL_RGB5_A1:
  238.       case GL_RGBA8:
  239.       case GL_RGB10_A2:
  240.       case GL_RGBA12:
  241.       case GL_RGBA16:
  242.          return 4;
  243.       default:
  244.          return -1;  /* error */
  245.    }
  246. }
  247.  
  248.  
  249.  
  250. struct gl_texture_image *gl_alloc_texture_image( void )
  251. {
  252.    return calloc( 1, sizeof(struct gl_texture_image) );
  253. }
  254.  
  255.  
  256.  
  257. void gl_free_texture_image( struct gl_texture_image *teximage )
  258. {
  259.    if (teximage->Data) {
  260.       free( teximage->Data );
  261.    }
  262.    free( teximage );
  263. }
  264.  
  265.  
  266.  
  267. /*
  268.  * Given a gl_image, apply the pixel transfer scale, bias, and mapping
  269.  * to produce a gl_texture_image.
  270.  * Input:  image - the incoming gl_image
  271.  *         internalFormat - desired format of resultant texture
  272.  *         border - texture border width (0 or 1)
  273.  * Return:  pointer to a gl_texture_image or NULL if an error occurs.
  274.  */
  275. struct gl_texture_image *gl_image_to_texture( GLcontext *ctx,
  276.                                               const struct gl_image *image,
  277.                                               GLenum internalFormat,
  278.                                               GLint border )
  279. {
  280.    GLint components;
  281.    struct gl_texture_image *texImage;
  282.    GLint numPixels, pixel;
  283.    GLboolean scaleOrBias;
  284.  
  285.    assert(image->Width>0);
  286.    assert(image->Height>0);
  287.    assert(image->Depth>0);
  288.  
  289.    internalFormat = decode_internal_format(internalFormat);
  290.    components = components_in_intformat(internalFormat);
  291.    numPixels = image->Width * image->Height * image->Depth;
  292.  
  293.    texImage = gl_alloc_texture_image();
  294.    texImage->Format = internalFormat;
  295.    texImage->Border = border;
  296.    texImage->Width = image->Width;
  297.    texImage->Height = image->Height;
  298.    texImage->Depth = image->Depth;
  299.    texImage->WidthLog2 = logbase2(image->Width - 2*border);
  300.    if (image->Height==1)  /* 1-D texture */
  301.       texImage->HeightLog2 = 0;
  302.    else
  303.       texImage->HeightLog2 = logbase2(image->Height - 2*border);
  304.    if (image->Depth==1)   /* 2-D texture */
  305.       texImage->DepthLog2 = 0;
  306.    else
  307.       texImage->DepthLog2 = logbase2(image->Depth - 2*border);
  308.    texImage->Width2 = 1 << texImage->WidthLog2;
  309.    texImage->Height2 = 1 << texImage->HeightLog2;
  310.    texImage->Depth2 = 1 << texImage->DepthLog2;
  311.    texImage->MaxLog2 = MAX2( texImage->WidthLog2, texImage->HeightLog2 );
  312.    texImage->Data = (GLubyte *) malloc( numPixels * components );
  313.  
  314.    assert(texImage->WidthLog2>=0);
  315.    assert(texImage->HeightLog2>=0);
  316.    assert(texImage->DepthLog2>=0);
  317.  
  318.    if (!texImage->Data) {
  319.       /* out of memory */
  320.       gl_free_texture_image( texImage );
  321.       return NULL;
  322.    }
  323.  
  324.    /* Determine if scaling and/or biasing is needed */
  325.    if (ctx->Pixel.RedScale!=1.0F   || ctx->Pixel.RedBias!=0.0F ||
  326.        ctx->Pixel.GreenScale!=1.0F || ctx->Pixel.GreenBias!=0.0F ||
  327.        ctx->Pixel.BlueScale!=1.0F  || ctx->Pixel.BlueBias!=0.0F ||
  328.        ctx->Pixel.AlphaScale!=1.0F || ctx->Pixel.AlphaBias!=0.0F) {
  329.       scaleOrBias = GL_TRUE;
  330.    }
  331.    else {
  332.       scaleOrBias = GL_FALSE;
  333.    }
  334.  
  335.    switch (image->Type) {
  336.       case GL_BITMAP:
  337.          {
  338.             GLint shift = ctx->Pixel.IndexShift;
  339.             GLint offset = ctx->Pixel.IndexOffset;
  340.             /* MapIto[RGBA]Size must be powers of two */
  341.             GLint rMask = ctx->Pixel.MapItoRsize-1;
  342.             GLint gMask = ctx->Pixel.MapItoGsize-1;
  343.             GLint bMask = ctx->Pixel.MapItoBsize-1;
  344.             GLint aMask = ctx->Pixel.MapItoAsize-1;
  345.             GLint i, j;
  346.             GLubyte *srcPtr = (GLubyte *) image->Data;
  347.  
  348.             assert( image->Format==GL_COLOR_INDEX );
  349.  
  350.             for (j=0; j<image->Height; j++) {
  351.                GLubyte bitMask = 128;
  352.                for (i=0; i<image->Width; i++) {
  353.                   GLint index;
  354.                   GLubyte red, green, blue, alpha;
  355.  
  356.                   /* Fetch image color index */
  357.                   index = (*srcPtr & bitMask) ? 1 : 0;
  358.                   bitMask = bitMask >> 1;
  359.                   if (bitMask==0) {
  360.                      bitMask = 128;
  361.                      srcPtr++;
  362.                   }
  363.                   /* apply index shift and offset */
  364.                   if (shift>=0) {
  365.                      index = (index << shift) + offset;
  366.                   }
  367.                   else {
  368.                      index = (index >> -shift) + offset;
  369.                   }
  370.                   /* convert index to RGBA */
  371.                   red   = (GLint) (ctx->Pixel.MapItoR[index & rMask] * 255.0F);
  372.                   green = (GLint) (ctx->Pixel.MapItoG[index & gMask] * 255.0F);
  373.                   blue  = (GLint) (ctx->Pixel.MapItoB[index & bMask] * 255.0F);
  374.                   alpha = (GLint) (ctx->Pixel.MapItoA[index & aMask] * 255.0F);
  375.  
  376.                   /* store texel (components are GLubytes in [0,255]) */
  377.                   pixel = j * image->Width + i;
  378.                   switch (internalFormat) {
  379.                      case GL_ALPHA:
  380.                         texImage->Data[pixel] = alpha;
  381.                         break;
  382.                      case GL_LUMINANCE:
  383.                         texImage->Data[pixel] = red;
  384.                         break;
  385.                      case GL_LUMINANCE_ALPHA:
  386.                         texImage->Data[pixel*2+0] = red;
  387.                         texImage->Data[pixel*2+1] = alpha;
  388.                         break;
  389.                      case GL_INTENSITY:
  390.                         texImage->Data[pixel] = red;
  391.                         break;
  392.                      case GL_RGB:
  393.                         texImage->Data[pixel*3+0] = red;
  394.                         texImage->Data[pixel*3+1] = green;
  395.                         texImage->Data[pixel*3+2] = blue;
  396.                         break;
  397.                      case GL_RGBA:
  398.                         texImage->Data[pixel*4+0] = red;
  399.                         texImage->Data[pixel*4+1] = green;
  400.                         texImage->Data[pixel*4+2] = blue;
  401.                         texImage->Data[pixel*4+3] = alpha;
  402.                         break;
  403.                      default:
  404.                         abort();
  405.                   }
  406.                }
  407.                if (bitMask!=128) {
  408.                   srcPtr++;
  409.                }
  410.             }
  411.          }
  412.          break;
  413.  
  414.       case GL_UNSIGNED_BYTE:
  415.          for (pixel=0; pixel<numPixels; pixel++) {
  416.             GLubyte red, green, blue, alpha;
  417.             switch (image->Format) {
  418.                case GL_COLOR_INDEX:
  419.                   {
  420.                      GLint index = ((GLubyte*)image->Data)[pixel];
  421.                      red   = 255.0F * ctx->Pixel.MapItoR[index];
  422.                      green = 255.0F * ctx->Pixel.MapItoG[index];
  423.                      blue  = 255.0F * ctx->Pixel.MapItoB[index];
  424.                      alpha = 255;
  425.                   }
  426.                   break;
  427.                case GL_RGB:
  428.                   /* Fetch image RGBA values */
  429.                   red   = ((GLubyte*) image->Data)[pixel*3+0];
  430.                   green = ((GLubyte*) image->Data)[pixel*3+1];
  431.                   blue  = ((GLubyte*) image->Data)[pixel*3+2];
  432.                   alpha = 255;
  433.                   break;
  434.                case GL_RGBA:
  435.                   red   = ((GLubyte*) image->Data)[pixel*4+0];
  436.                   green = ((GLubyte*) image->Data)[pixel*4+1];
  437.                   blue  = ((GLubyte*) image->Data)[pixel*4+2];
  438.                   alpha = ((GLubyte*) image->Data)[pixel*4+3];
  439.                   break;
  440.                case GL_RED:
  441.                   red   = ((GLubyte*) image->Data)[pixel];
  442.                   green = 0;
  443.                   blue  = 0;
  444.                   alpha = 255;
  445.                   break;
  446.                case GL_GREEN:
  447.                   red   = 0;
  448.                   green = ((GLubyte*) image->Data)[pixel];
  449.                   blue  = 0;
  450.                   alpha = 255;
  451.                   break;
  452.                case GL_BLUE:
  453.                   red   = 0;
  454.                   green = 0;
  455.                   blue  = ((GLubyte*) image->Data)[pixel];
  456.                   alpha = 255;
  457.                   break;
  458.                case GL_ALPHA:
  459.                   red   = 0;
  460.                   green = 0;
  461.                   blue  = 0;
  462.                   alpha = ((GLubyte*) image->Data)[pixel];
  463.                   break;
  464.                case GL_LUMINANCE: 
  465.                   red   = ((GLubyte*) image->Data)[pixel];
  466.                   green = red;
  467.                   blue  = red;
  468.                   alpha = 255;
  469.                   break;
  470.               case GL_LUMINANCE_ALPHA:
  471.                   red   = ((GLubyte*) image->Data)[pixel*2+0];
  472.                   green = red;
  473.                   blue  = red;
  474.                   alpha = ((GLubyte*) image->Data)[pixel*2+1];
  475.                   break;
  476.               default:
  477.                   abort();
  478.             }
  479.             
  480.             if (scaleOrBias || ctx->Pixel.MapColorFlag) {
  481.                /* Apply RGBA scale and bias */
  482.                GLfloat r = red   * (1.0F/255.0F);
  483.                GLfloat g = green * (1.0F/255.0F);
  484.                GLfloat b = blue  * (1.0F/255.0F);
  485.                GLfloat a = alpha * (1.0F/255.0F);
  486.                if (scaleOrBias) {
  487.                   /* r,g,b,a now in [0,1] */
  488.                   r = r * ctx->Pixel.RedScale   + ctx->Pixel.RedBias;
  489.                   g = g * ctx->Pixel.GreenScale + ctx->Pixel.GreenBias;
  490.                   b = b * ctx->Pixel.BlueScale  + ctx->Pixel.BlueBias;
  491.                   a = a * ctx->Pixel.AlphaScale + ctx->Pixel.AlphaBias;
  492.                   r = CLAMP( r, 0.0F, 1.0F );
  493.                   g = CLAMP( g, 0.0F, 1.0F );
  494.                   b = CLAMP( b, 0.0F, 1.0F );
  495.                   a = CLAMP( a, 0.0F, 1.0F );
  496.                }
  497.                /* Apply pixel maps */
  498.                if (ctx->Pixel.MapColorFlag) {
  499.                   GLint ir = (GLint) (r*ctx->Pixel.MapRtoRsize);
  500.                   GLint ig = (GLint) (g*ctx->Pixel.MapGtoGsize);
  501.                   GLint ib = (GLint) (b*ctx->Pixel.MapBtoBsize);
  502.                   GLint ia = (GLint) (a*ctx->Pixel.MapAtoAsize);
  503.                   r = ctx->Pixel.MapRtoR[ir];
  504.                   g = ctx->Pixel.MapGtoG[ig];
  505.                   b = ctx->Pixel.MapBtoB[ib];
  506.                   a = ctx->Pixel.MapAtoA[ia];
  507.                }
  508.                red   = (GLint) (r * 255.0F);
  509.                green = (GLint) (g * 255.0F);
  510.                blue  = (GLint) (b * 255.0F);
  511.                alpha = (GLint) (a * 255.0F);
  512.             }
  513.  
  514.             /* store texel (components are GLubytes in [0,255]) */
  515.             switch (internalFormat) {
  516.                case GL_ALPHA:
  517.                   texImage->Data[pixel] = alpha;
  518.                   break;
  519.                case GL_LUMINANCE:
  520.                   texImage->Data[pixel] = red;
  521.                   break;
  522.                case GL_LUMINANCE_ALPHA:
  523.                   texImage->Data[pixel*2+0] = red;
  524.                   texImage->Data[pixel*2+1] = alpha;
  525.                   break;
  526.                case GL_INTENSITY:
  527.                   texImage->Data[pixel] = red;
  528.                   break;
  529.                case GL_RGB:
  530.                   texImage->Data[pixel*3+0] = red;
  531.                   texImage->Data[pixel*3+1] = green;
  532.                   texImage->Data[pixel*3+2] = blue;
  533.                   break;
  534.                case GL_RGBA:
  535.                   texImage->Data[pixel*4+0] = red;
  536.                   texImage->Data[pixel*4+1] = green;
  537.                   texImage->Data[pixel*4+2] = blue;
  538.                   texImage->Data[pixel*4+3] = alpha;
  539.                   break;
  540.                default:
  541.                   abort();
  542.             }
  543.          }
  544.          break;
  545.  
  546.       case GL_FLOAT:
  547.          for (pixel=0; pixel<numPixels; pixel++) {
  548.             GLfloat red, green, blue, alpha;
  549.             switch (image->Format) {
  550.                case GL_COLOR_INDEX:
  551.                   {
  552.                      GLint shift = ctx->Pixel.IndexShift;
  553.                      GLint offset = ctx->Pixel.IndexOffset;
  554.                      /* MapIto[RGBA]Size must be powers of two */
  555.                      GLint rMask = ctx->Pixel.MapItoRsize-1;
  556.                      GLint gMask = ctx->Pixel.MapItoGsize-1;
  557.                      GLint bMask = ctx->Pixel.MapItoBsize-1;
  558.                      GLint aMask = ctx->Pixel.MapItoAsize-1;
  559.                      /* Fetch image color index */
  560.                      GLint index = (GLint) ((GLfloat*) image->Data)[pixel];
  561.                      /* apply index shift and offset */
  562.                      if (shift>=0) {
  563.                         index = (index << shift) + offset;
  564.                      }
  565.                      else {
  566.                         index = (index >> -shift) + offset;
  567.                      }
  568.                      /* convert index to RGBA */
  569.                      red   = ctx->Pixel.MapItoR[index & rMask];
  570.                      green = ctx->Pixel.MapItoG[index & gMask];
  571.                      blue  = ctx->Pixel.MapItoB[index & bMask];
  572.                      alpha = ctx->Pixel.MapItoA[index & aMask];
  573.                   }
  574.                   break;
  575.                case GL_RGB:
  576.                   /* Fetch image RGBA values */
  577.                   red   = ((GLfloat*) image->Data)[pixel*3+0];
  578.                   green = ((GLfloat*) image->Data)[pixel*3+1];
  579.                   blue  = ((GLfloat*) image->Data)[pixel*3+2];
  580.                   alpha = 1.0;
  581.                   break;
  582.                case GL_RGBA:
  583.                   red   = ((GLfloat*) image->Data)[pixel*4+0];
  584.                   green = ((GLfloat*) image->Data)[pixel*4+1];
  585.                   blue  = ((GLfloat*) image->Data)[pixel*4+2];
  586.                   alpha = ((GLfloat*) image->Data)[pixel*4+3];
  587.                   break;
  588.                case GL_RED:
  589.                   red   = ((GLfloat*) image->Data)[pixel];
  590.                   green = 0.0;
  591.                   blue  = 0.0;
  592.                   alpha = 1.0;
  593.                   break;
  594.                case GL_GREEN:
  595.                   red   = 0.0;
  596.                   green = ((GLfloat*) image->Data)[pixel];
  597.                   blue  = 0.0;
  598.                   alpha = 1.0;
  599.                   break;
  600.                case GL_BLUE:
  601.                   red   = 0.0;
  602.                   green = 0.0;
  603.                   blue  = ((GLfloat*) image->Data)[pixel];
  604.                   alpha = 1.0;
  605.                   break;
  606.                case GL_ALPHA:
  607.                   red   = 0.0;
  608.                   green = 0.0;
  609.                   blue  = 0.0;
  610.                   alpha = ((GLfloat*) image->Data)[pixel];
  611.                   break;
  612.                case GL_LUMINANCE: 
  613.                   red   = ((GLfloat*) image->Data)[pixel];
  614.                   green = red;
  615.                   blue  = red;
  616.                   alpha = 1.0;
  617.                   break;
  618.               case GL_LUMINANCE_ALPHA:
  619.                   red   = ((GLfloat*) image->Data)[pixel*2+0];
  620.                   green = red;
  621.                   blue  = red;
  622.                   alpha = ((GLfloat*) image->Data)[pixel*2+1];
  623.                   break;
  624.                default:
  625.                   abort();
  626.             }
  627.             
  628.             if (image->Format!=GL_COLOR_INDEX) {
  629.                /* Apply RGBA scale and bias */
  630.                if (scaleOrBias) {
  631.                   red   = red   * ctx->Pixel.RedScale   + ctx->Pixel.RedBias;
  632.                   green = green * ctx->Pixel.GreenScale + ctx->Pixel.GreenBias;
  633.                   blue  = blue  * ctx->Pixel.BlueScale  + ctx->Pixel.BlueBias;
  634.                   alpha = alpha * ctx->Pixel.AlphaScale + ctx->Pixel.AlphaBias;
  635.                   red   = CLAMP( red,    0.0F, 1.0F );
  636.                   green = CLAMP( green,  0.0F, 1.0F );
  637.                   blue  = CLAMP( blue,   0.0F, 1.0F );
  638.                   alpha = CLAMP( alpha,  0.0F, 1.0F );
  639.                }
  640.                /* Apply pixel maps */
  641.                if (ctx->Pixel.MapColorFlag) {
  642.                   GLint ir = (GLint) (red  *ctx->Pixel.MapRtoRsize);
  643.                   GLint ig = (GLint) (green*ctx->Pixel.MapGtoGsize);
  644.                   GLint ib = (GLint) (blue *ctx->Pixel.MapBtoBsize);
  645.                   GLint ia = (GLint) (alpha*ctx->Pixel.MapAtoAsize);
  646.                   red   = ctx->Pixel.MapRtoR[ir];
  647.                   green = ctx->Pixel.MapGtoG[ig];
  648.                   blue  = ctx->Pixel.MapBtoB[ib];
  649.                   alpha = ctx->Pixel.MapAtoA[ia];
  650.                }
  651.             }
  652.  
  653.             /* store texel (components are GLubytes in [0,255]) */
  654.             switch (internalFormat) {
  655.                case GL_ALPHA:
  656.                   texImage->Data[pixel] = (GLint) (alpha * 255.0F);
  657.                   break;
  658.                case GL_LUMINANCE:
  659.                   texImage->Data[pixel] = (GLint) (red * 255.0F);
  660.                   break;
  661.                case GL_LUMINANCE_ALPHA:
  662.                   texImage->Data[pixel*2+0] = (GLint) (red * 255.0F);
  663.                   texImage->Data[pixel*2+1] = (GLint) (alpha * 255.0F);
  664.                   break;
  665.                case GL_INTENSITY:
  666.                   texImage->Data[pixel] = (GLint) (red * 255.0F);
  667.                   break;
  668.                case GL_RGB:
  669.                   texImage->Data[pixel*3+0] = (GLint) (red   * 255.0F);
  670.                   texImage->Data[pixel*3+1] = (GLint) (green * 255.0F);
  671.                   texImage->Data[pixel*3+2] = (GLint) (blue  * 255.0F);
  672.                   break;
  673.                case GL_RGBA:
  674.                   texImage->Data[pixel*4+0] = (GLint) (red   * 255.0F);
  675.                   texImage->Data[pixel*4+1] = (GLint) (green * 255.0F);
  676.                   texImage->Data[pixel*4+2] = (GLint) (blue  * 255.0F);
  677.                   texImage->Data[pixel*4+3] = (GLint) (alpha * 255.0F);
  678.                   break;
  679.                default:
  680.                   abort();
  681.             }
  682.          }
  683.          break;
  684.  
  685.       default:
  686.          abort();
  687.    }
  688.  
  689.    return texImage;
  690. }
  691.  
  692.  
  693.  
  694.  
  695. /*
  696.  * Test glTexImagee1D() parameters for errors.
  697.  * Return:  GL_TRUE = an error was detected, GL_FALSE = no errors
  698.  */
  699. static GLboolean texture_1d_error_check( GLcontext *ctx, GLenum target,
  700.                                          GLint level, GLenum internalFormat,
  701.                                          GLenum format, GLenum type,
  702.                                          GLint width, GLint border )
  703. {
  704.    GLint iformat;
  705.    if (target!=GL_TEXTURE_1D && target!=GL_PROXY_TEXTURE_1D) {
  706.       gl_error( ctx, GL_INVALID_ENUM, "glTexImage1D" );
  707.       return GL_TRUE;
  708.    }
  709.    if (level<0 || level>=MAX_TEXTURE_LEVELS) {
  710.       gl_error( ctx, GL_INVALID_VALUE, "glTexImage1D(level)" );
  711.       return GL_TRUE;
  712.    }
  713.    iformat = decode_internal_format( internalFormat );
  714.    if (iformat<0) {
  715.       gl_error( ctx, GL_INVALID_VALUE, "glTexImage1D(internalFormat)" );
  716.       return GL_TRUE;
  717.    }
  718.    if (border!=0 && border!=1) {
  719.       if (target!=GL_PROXY_TEXTURE_1D) {
  720.          gl_error( ctx, GL_INVALID_VALUE, "glTexImage1D(border)" );
  721.       }
  722.       return GL_TRUE;
  723.    }
  724.    if (width<2*border || width>2+MAX_TEXTURE_SIZE) {
  725.       if (target!=GL_PROXY_TEXTURE_1D) {
  726.          gl_error( ctx, GL_INVALID_VALUE, "glTexImage1D(width)" );
  727.       }
  728.       return GL_TRUE;
  729.    }
  730.    if (logbase2( width-2*border )<0) {
  731.       gl_error( ctx, GL_INVALID_VALUE,
  732.                "glTexImage1D(width != 2^k + 2*border)");
  733.       return GL_TRUE;
  734.    }
  735.    switch (format) {
  736.       case GL_COLOR_INDEX:
  737.       case GL_RED:
  738.       case GL_GREEN:
  739.       case GL_BLUE:
  740.       case GL_ALPHA:
  741.       case GL_RGB:
  742.       case GL_RGBA:
  743.       case GL_LUMINANCE:
  744.       case GL_LUMINANCE_ALPHA:
  745.          /* OK */
  746.          break;
  747.       default:
  748.          gl_error( ctx, GL_INVALID_ENUM, "glTexImage1D(format)" );
  749.          return GL_TRUE;
  750.    }
  751.    switch (type) {
  752.       case GL_UNSIGNED_BYTE:
  753.       case GL_BYTE:
  754.       case GL_UNSIGNED_SHORT:
  755.       case GL_SHORT:
  756.       case GL_FLOAT:
  757.          /* OK */
  758.          break;
  759.       default:
  760.          gl_error( ctx, GL_INVALID_ENUM, "glTexImage1D(type)" );
  761.          return GL_TRUE;
  762.    }
  763.    return GL_FALSE;
  764. }
  765.  
  766.  
  767. /*
  768.  * Test glTexImagee2D() parameters for errors.
  769.  * Return:  GL_TRUE = an error was detected, GL_FALSE = no errors
  770.  */
  771. static GLboolean texture_2d_error_check( GLcontext *ctx, GLenum target,
  772.                                          GLint level, GLenum internalFormat,
  773.                                          GLenum format, GLenum type,
  774.                                          GLint width, GLint height,
  775.                                          GLint border )
  776. {
  777.    GLint iformat;
  778.    if (target!=GL_TEXTURE_2D && target!=GL_PROXY_TEXTURE_2D) {
  779.       gl_error( ctx, GL_INVALID_ENUM, "glTexImage2D(target)" );
  780.       return GL_TRUE;
  781.    }
  782.    if (level<0 || level>=MAX_TEXTURE_LEVELS) {
  783.       gl_error( ctx, GL_INVALID_VALUE, "glTexImage2D(level)" );
  784.       return GL_TRUE;
  785.    }
  786.    iformat = decode_internal_format( internalFormat );
  787.    if (iformat<0) {
  788.       gl_error( ctx, GL_INVALID_VALUE, "glTexImage2D(internalFormat)" );
  789.       return GL_TRUE;
  790.    }
  791.    if (border!=0 && border!=1) {
  792.       if (target!=GL_PROXY_TEXTURE_2D) {
  793.          gl_error( ctx, GL_INVALID_VALUE, "glTexImage2D(border)" );
  794.       }
  795.       return GL_TRUE;
  796.    }
  797.    if (width<2*border || width>2+MAX_TEXTURE_SIZE) {
  798.       if (target!=GL_PROXY_TEXTURE_2D) {
  799.          gl_error( ctx, GL_INVALID_VALUE, "glTexImage2D(width)" );
  800.       }
  801.       return GL_TRUE;
  802.    }
  803.    if (height<2*border || height>2+MAX_TEXTURE_SIZE) {
  804.       if (target!=GL_PROXY_TEXTURE_2D) {
  805.          gl_error( ctx, GL_INVALID_VALUE, "glTexImage2D(height)" );
  806.       }
  807.       return GL_TRUE;
  808.    }
  809.    if (logbase2( width-2*border )<0) {
  810.       gl_error( ctx,GL_INVALID_VALUE,
  811.                "glTexImage2D(width != 2^k + 2*border)");
  812.       return GL_TRUE;
  813.    }
  814.    if (logbase2( height-2*border )<0) {
  815.       gl_error( ctx,GL_INVALID_VALUE,
  816.                "glTexImage2D(height != 2^k + 2*border)");
  817.       return GL_TRUE;
  818.    }
  819.    switch (format) {
  820.       case GL_COLOR_INDEX:
  821.       case GL_RED:
  822.       case GL_GREEN:
  823.       case GL_BLUE:
  824.       case GL_ALPHA:
  825.       case GL_RGB:
  826.       case GL_RGBA:
  827.       case GL_LUMINANCE:
  828.       case GL_LUMINANCE_ALPHA:
  829.          /* OK */
  830.          break;
  831.       default:
  832.          gl_error( ctx, GL_INVALID_ENUM, "glTexImage2D(format)" );
  833.          return GL_TRUE;
  834.    }
  835.    switch (type) {
  836.       case GL_UNSIGNED_BYTE:
  837.       case GL_BYTE:
  838.       case GL_UNSIGNED_SHORT:
  839.       case GL_SHORT:
  840.       case GL_UNSIGNED_INT:
  841.       case GL_INT:
  842.       case GL_FLOAT:
  843.          /* OK */
  844.          break;
  845.       default:
  846.          gl_error( ctx, GL_INVALID_ENUM, "glTexImage2D(type)" );
  847.          return GL_TRUE;
  848.    }
  849.    return GL_FALSE;
  850. }
  851.  
  852.  
  853. /*
  854.  * Test glTexImage3DEXT() parameters for errors.
  855.  * Return:  GL_TRUE = an error was detected, GL_FALSE = no errors
  856.  */
  857. static GLboolean texture_3d_error_check( GLcontext *ctx, GLenum target,
  858.                                          GLint level, GLenum internalFormat,
  859.                                          GLenum format, GLenum type,
  860.                                          GLint width, GLint height,
  861.                                          GLint depth, GLint border )
  862. {
  863.    GLint iformat;
  864.    if (target!=GL_TEXTURE_3D_EXT && target!=GL_PROXY_TEXTURE_3D_EXT) {
  865.       gl_error( ctx, GL_INVALID_ENUM, "glTexImage3DEXT(target)" );
  866.       return GL_TRUE;
  867.    }
  868.    if (level<0 || level>=MAX_TEXTURE_LEVELS) {
  869.       gl_error( ctx, GL_INVALID_VALUE, "glTexImage3DEXT(level)" );
  870.       return GL_TRUE;
  871.    }
  872.    iformat = decode_internal_format( internalFormat );
  873.    if (iformat<0) {
  874.       gl_error( ctx, GL_INVALID_VALUE, "glTexImage3DEXT(internalFormat)" );
  875.       return GL_TRUE;
  876.    }
  877.    if (border!=0 && border!=1) {
  878.       if (target!=GL_PROXY_TEXTURE_3D_EXT) {
  879.          gl_error( ctx, GL_INVALID_VALUE, "glTexImage3DEXT(border)" );
  880.       }
  881.       return GL_TRUE;
  882.    }
  883.    if (width<2*border || width>2+MAX_TEXTURE_SIZE) {
  884.       if (target!=GL_PROXY_TEXTURE_3D_EXT) {
  885.          gl_error( ctx, GL_INVALID_VALUE, "glTexImage3DEXT(width)" );
  886.       }
  887.       return GL_TRUE;
  888.    }
  889.    if (height<2*border || height>2+MAX_TEXTURE_SIZE) {
  890.       if (target!=GL_PROXY_TEXTURE_3D_EXT) {
  891.          gl_error( ctx, GL_INVALID_VALUE, "glTexImage3DEXT(height)" );
  892.       }
  893.       return GL_TRUE;
  894.    }
  895.    if (depth<2*border || depth>2+MAX_TEXTURE_SIZE) {
  896.       if (target!=GL_PROXY_TEXTURE_3D_EXT) {
  897.          gl_error( ctx, GL_INVALID_VALUE, "glTexImage3DEXT(depth)" );
  898.       }
  899.       return GL_TRUE;
  900.    }
  901.    if (logbase2( width-2*border )<0) {
  902.       gl_error( ctx,GL_INVALID_VALUE,
  903.                "glTexImage3DEXT(width != 2^k + 2*border))");
  904.       return GL_TRUE;
  905.    }
  906.    if (logbase2( height-2*border )<0) {
  907.       gl_error( ctx,GL_INVALID_VALUE,
  908.                "glTexImage3DEXT(height != 2^k + 2*border))");
  909.       return GL_TRUE;
  910.    }
  911.    if (logbase2( depth-2*border )<0) {
  912.       gl_error( ctx,GL_INVALID_VALUE,
  913.                "glTexImage3DEXT(depth  != 2^k + 2*border))");
  914.       return GL_TRUE;
  915.    }
  916.    switch (format) {
  917.       case GL_COLOR_INDEX:
  918.       case GL_RED:
  919.       case GL_GREEN:
  920.       case GL_BLUE:
  921.       case GL_ALPHA:
  922.       case GL_RGB:
  923.       case GL_RGBA:
  924.       case GL_LUMINANCE:
  925.       case GL_LUMINANCE_ALPHA:
  926.          /* OK */
  927.          break;
  928.       default:
  929.          gl_error( ctx, GL_INVALID_ENUM, "glTexImage3DEXT(format)" );
  930.          return GL_TRUE;
  931.    }
  932.    switch (type) {
  933.       case GL_UNSIGNED_BYTE:
  934.       case GL_BYTE:
  935.       case GL_UNSIGNED_SHORT:
  936.       case GL_SHORT:
  937.       case GL_UNSIGNED_INT:
  938.       case GL_INT:
  939.       case GL_FLOAT:
  940.          /* OK */
  941.          break;
  942.       default:
  943.          gl_error( ctx, GL_INVALID_ENUM, "glTexImage3DEXT(type)" );
  944.          return GL_TRUE;
  945.    }
  946.    return GL_FALSE;
  947. }
  948.  
  949.  
  950.  
  951. /*
  952.  * Called from the API.  Note that width includes the border.
  953.  */
  954. void gl_TexImage1D( GLcontext *ctx,
  955.                     GLenum target, GLint level, GLint internalformat,
  956.             GLsizei width, GLint border, GLenum format,
  957.             GLenum type, struct gl_image *image )
  958. {
  959.    if (INSIDE_BEGIN_END(ctx)) {
  960.       gl_error( ctx, GL_INVALID_OPERATION, "glTexImage1D" );
  961.       return;
  962.    }
  963.  
  964.    if (image) {
  965.       /* if image is not NULL then it's probably valid... */
  966.       if (target==GL_TEXTURE_1D) {
  967.          struct gl_texture_image *teximage;
  968.          if (texture_1d_error_check( ctx, target, level, internalformat,
  969.                                      format, type, width, border )) {
  970.             /* error in texture image was detected */
  971.             return;
  972.          }
  973.          /* free current texture image, if any */
  974.          if (ctx->Texture.Current1D->Image[level]) {
  975.             gl_free_texture_image( ctx->Texture.Current1D->Image[level] );
  976.          }
  977.          /* install new texture image */
  978.          teximage = gl_image_to_texture( ctx, image, internalformat, border );
  979.          if (image->RefCount==0) {
  980.             /* if RefCount==1 then image must be in a display list */
  981.             gl_free_image(image);
  982.          }
  983.          ctx->Texture.Current1D->Image[level] = teximage;
  984.          ctx->NewState |= NEW_TEXTURING;
  985.  
  986.          /* Send texture image to device driver */
  987.          if (ctx->Driver.TexImage) {
  988.             (*ctx->Driver.TexImage)( ctx, GL_TEXTURE_1D,
  989.                                      ctx->Texture.Current1D->Name,
  990.                                      level, internalformat, teximage );
  991.          }
  992.       }
  993.       else if (target==GL_PROXY_TEXTURE_1D) {
  994.          /* Proxy texture: check for errors and update proxy state */
  995.          if (texture_1d_error_check( ctx, target, level, internalformat,
  996.                                      format, type, width, border )) {
  997.             if (level>=0 && level<MAX_TEXTURE_LEVELS) {
  998.                MEMSET( ctx->Texture.Proxy1D->Image[level], 0,
  999.                       sizeof(struct gl_texture_image) );
  1000.             }
  1001.          }
  1002.          else {
  1003.             ctx->Texture.Proxy1D->Image[level]->Format = internalformat;
  1004.             ctx->Texture.Proxy1D->Image[level]->Border = border;
  1005.             ctx->Texture.Proxy1D->Image[level]->Width = width;
  1006.             ctx->Texture.Proxy1D->Image[level]->Height = 1;
  1007.          }
  1008.          if (image->RefCount==0) {
  1009.             /* if RefCount==1 then image must be in a display list */
  1010.             gl_free_image(image);
  1011.          }
  1012.       }
  1013.       else {
  1014.          gl_error( ctx, GL_INVALID_ENUM, "glTexImage1D(target)" );
  1015.          return;
  1016.       }
  1017.    }
  1018.    else {
  1019.       /* An error must have occured during texture unpacking.  Record the
  1020.        * error now.
  1021.        */
  1022.       (void) texture_1d_error_check( ctx, target, level, internalformat,
  1023.                                      format, type, width, border );
  1024.    }
  1025. }
  1026.  
  1027.  
  1028.  
  1029.  
  1030. /*
  1031.  * Called by the API or display list executor.
  1032.  * Note that width and height include the border.
  1033.  */
  1034. void gl_TexImage2D( GLcontext *ctx,
  1035.                     GLenum target, GLint level, GLint internalformat,
  1036.                     GLsizei width, GLsizei height, GLint border,
  1037.                     GLenum format, GLenum type,
  1038.                     struct gl_image *image )
  1039. {
  1040.    if (INSIDE_BEGIN_END(ctx)) {
  1041.       gl_error( ctx, GL_INVALID_OPERATION, "glTexImage2D" );
  1042.       return;
  1043.    }
  1044.  
  1045.    if (image) {
  1046.       /* if image is not NULL then it's probably valid... */
  1047.       if (target==GL_TEXTURE_2D) {
  1048.          struct gl_texture_image *teximage;
  1049.          if (texture_2d_error_check( ctx, target, level, internalformat,
  1050.                                      format, type, width, height, border )) {
  1051.             /* error in texture image was detected */
  1052.             return;
  1053.          }
  1054.          /* free current texture image, if any */
  1055.          if (ctx->Texture.Current2D->Image[level]) {
  1056.             gl_free_texture_image( ctx->Texture.Current2D->Image[level] );
  1057.          }
  1058.          /* install new texture image */
  1059.          teximage = gl_image_to_texture( ctx, image, internalformat, border );
  1060.          if (image->RefCount==0) {
  1061.             /* if RefCount==1 then image must be in a display list */
  1062.             gl_free_image(image);
  1063.          }
  1064.          ctx->Texture.Current2D->Image[level] = teximage;
  1065.          ctx->NewState |= NEW_TEXTURING;
  1066.  
  1067.          /* Send texture image to device driver */
  1068.          if (ctx->Driver.TexImage) {
  1069.             (*ctx->Driver.TexImage)( ctx, GL_TEXTURE_2D,
  1070.                                      ctx->Texture.Current2D->Name,
  1071.                                      level, internalformat, teximage );
  1072.          }
  1073.       }
  1074.       else if (target==GL_PROXY_TEXTURE_2D) {
  1075.          /* Proxy texture: check for errors and update proxy state */
  1076.          if (texture_2d_error_check( ctx, target, level, internalformat,
  1077.                                      format, type, width, height, border )) {
  1078.             if (level>=0 && level<MAX_TEXTURE_LEVELS) {
  1079.                MEMSET( ctx->Texture.Proxy2D->Image[level], 0,
  1080.                       sizeof(struct gl_texture_image) );
  1081.             }
  1082.          }
  1083.          else {
  1084.             ctx->Texture.Proxy2D->Image[level]->Format = internalformat;
  1085.             ctx->Texture.Proxy2D->Image[level]->Border = border;
  1086.             ctx->Texture.Proxy2D->Image[level]->Width = width;
  1087.             ctx->Texture.Proxy2D->Image[level]->Height = height;
  1088.          }
  1089.          if (image->RefCount==0) {
  1090.             /* if RefCount==1 then image must be in a display list */
  1091.             gl_free_image(image);
  1092.          }
  1093.       }
  1094.       else {
  1095.          gl_error( ctx, GL_INVALID_ENUM, "glTexImage2D(target)" );
  1096.          return;
  1097.       }
  1098.    }
  1099.    else {
  1100.       /*
  1101.        * An error must have occured during texture unpacking.
  1102.        * Take care of reporting the error now.
  1103.        */
  1104.       (void) texture_2d_error_check( ctx, target, level, internalformat,
  1105.                                      format, type, width, height, border );
  1106.    }
  1107. }
  1108.  
  1109.  
  1110.  
  1111. /*
  1112.  * Called by the API or display list executor.
  1113.  * Note that width and height include the border.
  1114.  */
  1115. void gl_TexImage3DEXT( GLcontext *ctx,
  1116.                        GLenum target, GLint level, GLint internalformat,
  1117.                        GLsizei width, GLsizei height, GLsizei depth,
  1118.                        GLint border, GLenum format, GLenum type,
  1119.                        struct gl_image *image )
  1120. {
  1121.    if (INSIDE_BEGIN_END(ctx)) {
  1122.       gl_error( ctx, GL_INVALID_OPERATION, "glTexImage3DEXT" );
  1123.       return;
  1124.    }
  1125.  
  1126.    if (image) {
  1127.       /* if image is not NULL then it must be valid */
  1128.       if (target==GL_TEXTURE_3D_EXT) {
  1129.          struct gl_texture_image *teximage;
  1130.          if (texture_3d_error_check( ctx, target, level, internalformat,
  1131.                                      format, type, width, height, depth,
  1132.                                      border )) {
  1133.             /* error in texture image was detected */
  1134.             return;
  1135.          }
  1136.          /* free current texture image, if any */
  1137.          if (ctx->Texture.Current3D->Image[level]) {
  1138.             gl_free_texture_image( ctx->Texture.Current3D->Image[level] );
  1139.          }
  1140.          /* install new texture image */
  1141.          teximage = gl_image_to_texture( ctx, image, internalformat, border );
  1142.          if (image->RefCount==0) {
  1143.             /* if RefCount==1 then image must be in a display list */
  1144.             gl_free_image(image);
  1145.          }
  1146.          ctx->Texture.Current3D->Image[level] = teximage;
  1147.          ctx->NewState |= NEW_TEXTURING;
  1148.  
  1149.          /* Send texture image to device driver */
  1150.          /* TODO: device driver 3-D texture function */
  1151.       }
  1152.       else if (target==GL_PROXY_TEXTURE_3D_EXT) {
  1153.          /* Proxy texture: check for errors and update proxy state */
  1154.          if (texture_3d_error_check( ctx, target, level, internalformat,
  1155.                                      format, type, width, height, depth,
  1156.                                      border )) {
  1157.             if (level>=0 && level<MAX_TEXTURE_LEVELS) {
  1158.                MEMSET( ctx->Texture.Proxy3D->Image[level], 0,
  1159.                       sizeof(struct gl_texture_image) );
  1160.             }
  1161.          }
  1162.          else {
  1163.             ctx->Texture.Proxy3D->Image[level]->Format = internalformat;
  1164.             ctx->Texture.Proxy3D->Image[level]->Border = border;
  1165.             ctx->Texture.Proxy3D->Image[level]->Width = width;
  1166.             ctx->Texture.Proxy3D->Image[level]->Height = height;
  1167.             ctx->Texture.Proxy3D->Image[level]->Depth  = depth;
  1168.          }
  1169.          if (image->RefCount==0) {
  1170.             /* if RefCount==1 then image must be in a display list */
  1171.             gl_free_image(image);
  1172.          }
  1173.       }
  1174.       else {
  1175.          gl_error( ctx, GL_INVALID_ENUM, "glTexImage3DEXT(target)" );
  1176.          return;
  1177.       }
  1178.    }
  1179.    else {
  1180.       /*
  1181.        * An error must have occured during texture unpacking.
  1182.        * Take care of reporting the error now.
  1183.        */
  1184.       (void) texture_3d_error_check( ctx, target, level, internalformat,
  1185.                                      format, type, width, height, depth,
  1186.                                       border );
  1187.    }
  1188. }
  1189.  
  1190.  
  1191. void gl_GetTexImage( GLcontext *ctx, GLenum target, GLint level, GLenum format,
  1192.                      GLenum type, GLvoid *pixels )
  1193. {
  1194.    /* TODO */
  1195. }
  1196.  
  1197.  
  1198.  
  1199.  
  1200.  
  1201. /*
  1202.  * GL_EXT_copy_texture
  1203.  */
  1204.  
  1205.  
  1206.  
  1207. /*
  1208.  * Unpack the image data given to glTexSubImage[12]D.
  1209.  */
  1210. struct gl_image *
  1211. gl_unpack_texsubimage( GLcontext *ctx, GLint width, GLint height,
  1212.                        GLenum format, GLenum type, const GLvoid *pixels )
  1213. {
  1214.    GLint components;
  1215.    GLenum desttype;
  1216.  
  1217.    if (width<0 || height<0 || !pixels) {
  1218.       return NULL;
  1219.    }
  1220.  
  1221.    if (type==GL_BITMAP && format!=GL_COLOR_INDEX) {
  1222.       return NULL;
  1223.    }
  1224.  
  1225.    components = components_in_intformat( format );
  1226.    if (components<0 || format==GL_STENCIL_INDEX || format==GL_DEPTH_COMPONENT){
  1227.       return NULL;
  1228.    }
  1229.  
  1230.    if (gl_sizeof_type(type)<=0) {
  1231.       return NULL;
  1232.    }
  1233.  
  1234.    if (type==GL_UNSIGNED_BYTE) {
  1235.       desttype = GL_UNSIGNED_BYTE;
  1236.    }
  1237.    else {
  1238.       desttype = GL_FLOAT;
  1239.    }
  1240.    
  1241.    return gl_unpack_image( ctx, width, height, format, type,
  1242.                            desttype, pixels, GL_FALSE );
  1243. }
  1244.  
  1245.  
  1246. /*
  1247.  * Unpack the image data given to glTexSubImage3D.
  1248.  */
  1249. struct gl_image *
  1250. gl_unpack_texsubimage3D( GLcontext *ctx, GLint width, GLint height,
  1251.                          GLint depth, GLenum format, GLenum type,
  1252.                          const GLvoid *pixels )
  1253. {
  1254.    GLint components;
  1255.    GLenum desttype;
  1256.  
  1257.    if (width<0 || height<0 || depth<0 || !pixels) {
  1258.       return NULL;
  1259.    }
  1260.  
  1261.    if (type==GL_BITMAP && format!=GL_COLOR_INDEX) {
  1262.       return NULL;
  1263.    }
  1264.  
  1265.    components = components_in_intformat( format );
  1266.    if (components<0 || format==GL_STENCIL_INDEX || format==GL_DEPTH_COMPONENT) {
  1267.       return NULL;
  1268.    }
  1269.  
  1270.    if (gl_sizeof_type(type)<=0) {
  1271.       return NULL;
  1272.    }
  1273.  
  1274.    if (type==GL_UNSIGNED_BYTE) {
  1275.       desttype = GL_UNSIGNED_BYTE;
  1276.    }
  1277.    else {
  1278.       desttype = GL_FLOAT;
  1279.    }
  1280.   
  1281.    return gl_unpack_image3D( ctx, width, height, depth, format, type,
  1282.                            desttype, pixels, GL_FALSE );
  1283. }
  1284.  
  1285.  
  1286.  
  1287. void gl_TexSubImage1D( GLcontext *ctx,
  1288.                        GLenum target, GLint level, GLint xoffset,
  1289.                        GLsizei width, GLenum format, GLenum type,
  1290.                        struct gl_image *image )
  1291. {
  1292.    struct gl_texture_image *teximage;
  1293.  
  1294.    if (target!=GL_TEXTURE_1D) {
  1295.       gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage1D(target)" );
  1296.       return;
  1297.    }
  1298.    if (level<0 || level>=MAX_TEXTURE_LEVELS) {
  1299.       gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage1D(level)" );
  1300.       return;
  1301.    }
  1302.  
  1303.    teximage = ctx->Texture.Current1D->Image[level];
  1304.    if (!teximage) {
  1305.       gl_error( ctx, GL_INVALID_OPERATION, "glTexSubImage1D" );
  1306.       return;
  1307.    }
  1308.  
  1309.    if (xoffset < -teximage->Border) {
  1310.       gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage1D(xoffset)" );
  1311.       return;
  1312.    }
  1313.    if (xoffset + width > teximage->Width+teximage->Border) {
  1314.       gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage1D(xoffset+width)" );
  1315.       return;
  1316.    }
  1317.  
  1318.    if (image) {
  1319.       /* unpacking must have been error-free */
  1320.       GLint texcomponents, i, k;
  1321.       GLubyte *dst, *src;
  1322.  
  1323.       /* TODO: this is temporary.  If Type==GL_FLOAT or scale&bias needed */
  1324.       /* then do more work. */
  1325.       if (image->Type==GL_FLOAT) {
  1326.          gl_problem( ctx, "unimplemented texture type in glTexSubImage1D" );
  1327.          return;
  1328.       }
  1329.  
  1330.       texcomponents = components_in_intformat(teximage->Format);
  1331.  
  1332.       dst = teximage->Data + texcomponents * xoffset;
  1333.  
  1334.       if (texcomponents == image->Components) {
  1335.          MEMCPY( dst, image->Data, width * texcomponents );
  1336.       }
  1337.       else {
  1338.          /* TODO: this is a hack */
  1339.          gl_problem( ctx, "component mismatch in glTexSubImage1D" );
  1340.          for (i=0;i<width;i++) {
  1341.             for (k=0;k<texcomponents;k++) {
  1342.                dst[k] = src[k];
  1343.             }
  1344.             dst += texcomponents;
  1345.             src += image->Components;
  1346.          }
  1347.       }
  1348.    }
  1349.    else {
  1350.       /* if no image, an error must have occured, do more testing now */
  1351.       GLint components, size;
  1352.  
  1353.       if (width<0) {
  1354.          gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage1D(width)" );
  1355.          return;
  1356.       }
  1357.       if (type==GL_BITMAP && format!=GL_COLOR_INDEX) {
  1358.          gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage1D(format)" );
  1359.          return;
  1360.       }
  1361.       components = components_in_intformat( format );
  1362.       if (components<0 || format==GL_STENCIL_INDEX
  1363.           || format==GL_DEPTH_COMPONENT){
  1364.          gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage1D(format)" );
  1365.          return;
  1366.       }
  1367.       size = gl_sizeof_type( type );
  1368.       if (size<=0) {
  1369.          gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage1D(type)" );
  1370.          return;
  1371.       }
  1372.       /* if we get here, probably ran out of memory during unpacking */
  1373.       gl_error( ctx, GL_OUT_OF_MEMORY, "glTexSubImage1D" );
  1374.    }
  1375. }
  1376.  
  1377.  
  1378.  
  1379. void gl_TexSubImage2D( GLcontext *ctx,
  1380.                        GLenum target, GLint level,
  1381.                        GLint xoffset, GLint yoffset,
  1382.                        GLsizei width, GLsizei height,
  1383.                        GLenum format, GLenum type,
  1384.                        struct gl_image *image )
  1385. {
  1386.    struct gl_texture_image *teximage;
  1387.  
  1388.    if (target!=GL_TEXTURE_2D) {
  1389.       gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage2D(target)" );
  1390.       return;
  1391.    }
  1392.    if (level<0 || level>=MAX_TEXTURE_LEVELS) {
  1393.       gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage2D(level)" );
  1394.       return;
  1395.    }
  1396.  
  1397.    teximage = ctx->Texture.Current2D->Image[level];
  1398.    if (!teximage) {
  1399.       gl_error( ctx, GL_INVALID_OPERATION, "glTexSubImage2D" );
  1400.       return;
  1401.    }
  1402.  
  1403.    if (xoffset < -teximage->Border) {
  1404.       gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage2D(xoffset)" );
  1405.       return;
  1406.    }
  1407.    if (yoffset < -teximage->Border) {
  1408.       gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage2D(yoffset)" );
  1409.       return;
  1410.    }
  1411.    if (xoffset + width > teximage->Width+teximage->Border) {
  1412.       gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage2D(xoffset+width)" );
  1413.       return;
  1414.    }
  1415.    if (yoffset + height > teximage->Height+teximage->Border) {
  1416.       gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage2D(yoffset+height)" );
  1417.       return;
  1418.    }
  1419.  
  1420.    if (image) {
  1421.       /* unpacking must have been error-free */
  1422.       GLint texcomponents, i, j, k;
  1423.       GLubyte *dst, *src;
  1424.  
  1425.       /* TODO: this is temporary.  If Type==GL_FLOAT or scale&bias needed */
  1426.       /* then do more work. */
  1427.       if (image->Type==GL_FLOAT) {
  1428.          gl_problem( ctx, "unimplemented texture type in glTexSubImage2D" );
  1429.          return;
  1430.       }
  1431.  
  1432.       texcomponents = components_in_intformat(teximage->Format);
  1433.  
  1434.       if (texcomponents == image->Components) {
  1435.          dst = teximage->Data 
  1436.                + (yoffset * teximage->Width + xoffset) * texcomponents;
  1437.          src = image->Data;
  1438.          for (j=0;j<height;j++) {
  1439.             MEMCPY( dst, src, width * texcomponents );
  1440.             dst += teximage->Width * texcomponents;
  1441.             src += width * texcomponents;
  1442.          }
  1443.       }
  1444.       else {
  1445.          /* TODO: this is a hack */
  1446.          gl_problem( ctx, "component mismatch in glTexSubImage2D" );
  1447.  
  1448.          for (j=0;j<height;j++) {
  1449.             dst = teximage->Data 
  1450.                + ((yoffset+j) * teximage->Width + xoffset) * texcomponents;
  1451.             src = (GLubyte *) image->Data + j * width * image->Components;
  1452.             for (i=0;i<width;i++) {
  1453.                for (k=0;k<texcomponents;k++) {
  1454.                   dst[k] = src[k];
  1455.                }
  1456.                dst += texcomponents;
  1457.                src += image->Components;
  1458.             }
  1459.          }
  1460.       }
  1461.    }
  1462.    else {
  1463.       /* if no image, an error must have occured, do more testing now */
  1464.       GLint components, size;
  1465.  
  1466.       if (width<0) {
  1467.          gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage2D(width)" );
  1468.          return;
  1469.       }
  1470.       if (height<0) {
  1471.          gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage2D(height)" );
  1472.          return;
  1473.       }
  1474.       if (type==GL_BITMAP && format!=GL_COLOR_INDEX) {
  1475.          gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage1D(format)" );
  1476.          return;
  1477.       }
  1478.       components = components_in_intformat( format );
  1479.       if (components<0 || format==GL_STENCIL_INDEX
  1480.           || format==GL_DEPTH_COMPONENT){
  1481.          gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage2D(format)" );
  1482.          return;
  1483.       }
  1484.       size = gl_sizeof_type( type );
  1485.       if (size<=0) {
  1486.          gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage2D(type)" );
  1487.          return;
  1488.       }
  1489.       /* if we get here, probably ran out of memory during unpacking */
  1490.       gl_error( ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D" );
  1491.    }
  1492. }
  1493.  
  1494.  
  1495.  
  1496. void gl_TexSubImage3DEXT( GLcontext *ctx,
  1497.                           GLenum target, GLint level,
  1498.                           GLint xoffset, GLint yoffset, GLint zoffset,
  1499.                           GLsizei width, GLsizei height, GLsizei depth,
  1500.                           GLenum format, GLenum type,
  1501.                           struct gl_image *image )
  1502. {
  1503.    struct gl_texture_image *teximage;
  1504.  
  1505.    if (target!=GL_TEXTURE_3D_EXT) {
  1506.       gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage3DEXT(target)" );
  1507.       return;
  1508.    }
  1509.    if (level<0 || level>=MAX_TEXTURE_LEVELS) {
  1510.       gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage3DEXT(level)" );
  1511.       return;
  1512.    }
  1513.  
  1514.    teximage = ctx->Texture.Current3D->Image[level];
  1515.    if (!teximage) {
  1516.       gl_error( ctx, GL_INVALID_OPERATION, "glTexSubImage3DEXT" );
  1517.       return;
  1518.    }
  1519.  
  1520.    if (xoffset < -teximage->Border) {
  1521.       gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage3DEXT(xoffset)" );
  1522.       return;
  1523.    }
  1524.    if (yoffset < -teximage->Border) {
  1525.       gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage3DEXT(yoffset)" );
  1526.       return;
  1527.    }
  1528.    if (zoffset < -teximage->Border) {
  1529.       gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage3DEXT(zoffset)" );
  1530.       return;
  1531.    }
  1532.    if (xoffset + width > teximage->Width+teximage->Border) {
  1533.       gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage3DEXT(xoffset+width)" );
  1534.       return;
  1535.    }
  1536.    if (yoffset + height > teximage->Height+teximage->Border) {
  1537.       gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage3DEXT(yoffset+height)" );
  1538.       return;
  1539.    }
  1540.    if (zoffset + depth  > teximage->Depth+teximage->Border) {
  1541.       gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage3DEXT(zoffset+depth)" );
  1542.       return;
  1543.    }
  1544.  
  1545.    if (image) {
  1546.       /* unpacking must have been error-free */
  1547.       GLint texcomponents, i, j, k, rectarea;
  1548.       GLubyte *dst, *src;
  1549.  
  1550.       /* TODO: this is temporary.  If Type==GL_FLOAT or scale&bias needed */
  1551.       /* then do more work. */
  1552.       if (image->Type==GL_FLOAT) {
  1553.          gl_problem( ctx, "unimplemented texture type in glTexSubImagDEXT" );
  1554.          return;
  1555.       }
  1556.  
  1557.       texcomponents = components_in_intformat(teximage->Format);
  1558.       rectarea=teximage->Width * teximage->Height;
  1559.  
  1560.       if (texcomponents == image->Components) {
  1561.          dst = teximage->Data
  1562.                + (zoffset * rectarea +  yoffset * teximage->Width + xoffset)
  1563.                * texcomponents;
  1564.          src = image->Data;
  1565.          for(k=0;k<depth; k++) {
  1566.            for (j=0;j<height;j++) {
  1567.               MEMCPY( dst, src, width * texcomponents );
  1568.               dst += teximage->Width * texcomponents;
  1569.               src += width * texcomponents;
  1570.            }
  1571.            dst += rectarea * texcomponents;
  1572.            src += rectarea * texcomponents;
  1573.          }
  1574.       }
  1575.       else {
  1576.          /* TODO: this is a hack */
  1577.          GLint l, trarea, tzoffset, tloffset;
  1578.  
  1579.          gl_problem( ctx, "component mismatch in glTexSubImage3DEXT" );
  1580.          trarea=width*depth * image->Components;
  1581.          for (l=0; l<depth; l++) {
  1582.             tzoffset=(zoffset+l) * rectarea;
  1583.             tloffset=l * trarea;
  1584.             for (j=0;j<height;j++) {
  1585.                dst = teximage->Data
  1586.                    + (tzoffset + (yoffset+j) * teximage->Width + xoffset)
  1587.                    * texcomponents;
  1588.                src = (GLubyte *) image->Data + tloffset + j * width * image->Components;
  1589.                for (i=0;i<width;i++) {
  1590.                   for (k=0;k<texcomponents;k++) {
  1591.                      dst[k] = src[k];
  1592.                   }
  1593.                   dst += texcomponents;
  1594.                   src += image->Components;
  1595.                }
  1596.             }
  1597.          }
  1598.       }
  1599.    }
  1600.    else {
  1601.       /* if no image, an error must have occured, do more testing now */
  1602.       GLint components, size;
  1603.  
  1604.       if (width<0) {
  1605.          gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage3DEXT(width)" );
  1606.          return;
  1607.       }
  1608.       if (height<0) {
  1609.          gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage3DEXT(height)" );
  1610.          return;
  1611.       }
  1612.       if (depth<0) {
  1613.          gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage3DEXT(depth)" );
  1614.          return;
  1615.       }
  1616.       if (type==GL_BITMAP && format!=GL_COLOR_INDEX) {
  1617.          gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage3DEXT(format)" );
  1618.          return;
  1619.       }
  1620.       components = components_in_intformat( format );
  1621.       if (components<0 || format==GL_STENCIL_INDEX
  1622.           || format==GL_DEPTH_COMPONENT){
  1623.          gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage3DEXT(format)" );
  1624.          return;
  1625.       }
  1626.       size = gl_sizeof_type( type );
  1627.       if (size<=0) {
  1628.          gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage3DEXT(type)" );
  1629.          return;
  1630.       }
  1631.       /* if we get here, probably ran out of memory during unpacking */
  1632.       gl_error( ctx, GL_OUT_OF_MEMORY, "glTexSubImage3DEXT" );
  1633.    }
  1634. }
  1635.  
  1636.  
  1637.  
  1638. /*
  1639.  * Read an RGBA image from the frame buffer.
  1640.  * Input:  ctx - the context
  1641.  *         x, y - lower left corner
  1642.  *         width, height - size of region to read
  1643.  *         format - one of GL_RED, GL_RGB, GL_LUMINANCE, etc.
  1644.  * Return: gl_image pointer or NULL if out of memory
  1645.  */
  1646. struct gl_image *gl_read_color_image( GLcontext *ctx, GLint x, GLint y,
  1647.                                       GLsizei width, GLsizei height,
  1648.                                       GLint format )
  1649. {
  1650.    struct gl_image *image;
  1651.    GLubyte *imgptr;
  1652.    GLint components;
  1653.    GLint i, j;
  1654.  
  1655.    components = components_in_intformat( format );
  1656.  
  1657.    /*
  1658.     * Allocate image struct and image data buffer
  1659.     */
  1660.    image = (struct gl_image *) malloc( sizeof(struct gl_image) );
  1661.    if (image) {
  1662.       image->Width = width;
  1663.       image->Height = height;
  1664.       image->Components = components;
  1665.       image->Format = format;
  1666.       image->Type = GL_UNSIGNED_BYTE;
  1667.       image->Interleaved = GL_FALSE;
  1668.       image->Data = (GLubyte *) malloc( width * height * components );
  1669.       if (!image->Data) {
  1670.          free(image);
  1671.          return NULL;
  1672.       }
  1673.    }
  1674.    else {
  1675.       return NULL;
  1676.    }
  1677.  
  1678.    imgptr = image->Data;
  1679.  
  1680.    /* Select buffer to read from */
  1681.    (void) (*ctx->Driver.SetBuffer)( ctx, ctx->Pixel.ReadBuffer );
  1682.  
  1683.    for (j=0;j<height;j++) {
  1684.       GLubyte red[MAX_WIDTH], green[MAX_WIDTH];
  1685.       GLubyte blue[MAX_WIDTH], alpha[MAX_WIDTH];
  1686.       gl_read_color_span( ctx, width, x, y+j, red, green, blue, alpha );
  1687.  
  1688.       if (!ctx->Visual->EightBitColor) {
  1689.          /* scale red, green, blue, alpha values to range [0,255] */
  1690.          GLfloat rscale = 255.0f * ctx->Visual->InvRedScale;
  1691.          GLfloat gscale = 255.0f * ctx->Visual->InvGreenScale;
  1692.          GLfloat bscale = 255.0f * ctx->Visual->InvBlueScale;
  1693.          GLfloat ascale = 255.0f * ctx->Visual->InvAlphaScale;
  1694.          for (i=0;i<width;i++) {
  1695.             red[i]   = (GLubyte) (GLint) (red[i]   * rscale);
  1696.             green[i] = (GLubyte) (GLint) (green[i] * gscale);
  1697.             blue[i]  = (GLubyte) (GLint) (blue[i]  * bscale);
  1698.             alpha[i] = (GLubyte) (GLint) (alpha[i] * ascale);
  1699.          }
  1700.       }
  1701.  
  1702.       switch (format) {
  1703.          case GL_ALPHA:
  1704.             for (i=0;i<width;i++) {
  1705.                *imgptr++ = alpha[i];
  1706.             }
  1707.             break;
  1708.          case GL_LUMINANCE:
  1709.             for (i=0;i<width;i++) {
  1710.                *imgptr++ = red[i];
  1711.             }
  1712.             break;
  1713.          case GL_LUMINANCE_ALPHA:
  1714.             for (i=0;i<width;i++) {
  1715.                *imgptr++ = red[i];
  1716.                *imgptr++ = alpha[i];
  1717.             }
  1718.             break;
  1719.          case GL_INTENSITY:
  1720.             for (i=0;i<width;i++) {
  1721.                *imgptr++ = red[i];
  1722.             }
  1723.             break;
  1724.          case GL_RGB:
  1725.             for (i=0;i<width;i++) {
  1726.                *imgptr++ = red[i];
  1727.                *imgptr++ = green[i];
  1728.                *imgptr++ = blue[i];
  1729.             }
  1730.             break;
  1731.          case GL_RGBA:
  1732.             for (i=0;i<width;i++) {
  1733.                *imgptr++ = red[i];
  1734.                *imgptr++ = green[i];
  1735.                *imgptr++ = blue[i];
  1736.                *imgptr++ = alpha[i];
  1737.             }
  1738.             break;
  1739.       } /*switch*/
  1740.  
  1741.    } /*for*/         
  1742.  
  1743.    /* Restore drawing buffer */
  1744.    (void) (*ctx->Driver.SetBuffer)( ctx, ctx->Color.DrawBuffer );
  1745.  
  1746.    return image;
  1747. }
  1748.  
  1749.  
  1750.  
  1751.  
  1752. void gl_CopyTexImage1D( GLcontext *ctx,
  1753.                         GLenum target, GLint level,
  1754.                         GLenum internalformat,
  1755.                         GLint x, GLint y,
  1756.                         GLsizei width, GLint border )
  1757. {
  1758.    GLint format;
  1759.    struct gl_image *teximage;
  1760.  
  1761.    if (INSIDE_BEGIN_END(ctx)) {
  1762.       gl_error( ctx, GL_INVALID_OPERATION, "glCopyTexImage1D" );
  1763.       return;
  1764.    }
  1765.    if (target!=GL_TEXTURE_1D) {
  1766.       gl_error( ctx, GL_INVALID_ENUM, "glCopyTexImage1D(target)" );
  1767.       return;
  1768.    }
  1769.    if (level<0 || level>=MAX_TEXTURE_LEVELS) {
  1770.       gl_error( ctx, GL_INVALID_VALUE, "glCopyTexImage1D(level)" );
  1771.       return;
  1772.    }
  1773.    if (border!=0 && border!=1) {
  1774.       gl_error( ctx, GL_INVALID_VALUE, "glCopyTexImage1D(border)" );
  1775.       return;
  1776.    }
  1777.    if (width<2*border || width>2+MAX_TEXTURE_SIZE || width<0) {
  1778.       gl_error( ctx, GL_INVALID_VALUE, "glCopyTexImage1D(width)" );
  1779.       return;
  1780.    }
  1781.    format = decode_internal_format( internalformat );
  1782.    if (format<0 || (internalformat>=1 && internalformat<=4)) {
  1783.       gl_error( ctx, GL_INVALID_VALUE, "glCopyTexImage1D(format)" );
  1784.       return;
  1785.    }
  1786.  
  1787.    teximage = gl_read_color_image( ctx, x, y, width, 1, format );
  1788.    if (!teximage) {
  1789.       gl_error( ctx, GL_OUT_OF_MEMORY, "glCopyTexImage1D" );
  1790.       return;
  1791.    }
  1792.  
  1793.    gl_TexImage1D( ctx, target, level, internalformat, width,
  1794.                   border, GL_RGBA, GL_UNSIGNED_BYTE, teximage );
  1795.  
  1796.    gl_free_image( teximage );
  1797. }
  1798.  
  1799.  
  1800.  
  1801. void gl_CopyTexImage2D( GLcontext *ctx,
  1802.                         GLenum target, GLint level, GLenum internalformat,
  1803.                         GLint x, GLint y, GLsizei width, GLsizei height,
  1804.                         GLint border )
  1805. {
  1806.    GLint format;
  1807.    struct gl_image *teximage;
  1808.  
  1809.    if (INSIDE_BEGIN_END(ctx)) {
  1810.       gl_error( ctx, GL_INVALID_OPERATION, "glCopyTexImage2D" );
  1811.       return;
  1812.    }
  1813.    if (target!=GL_TEXTURE_2D) {
  1814.       gl_error( ctx, GL_INVALID_ENUM, "glCopyTexImage2D(target)" );
  1815.       return;
  1816.    }
  1817.    if (level<0 || level>=MAX_TEXTURE_LEVELS) {
  1818.       gl_error( ctx, GL_INVALID_VALUE, "glCopyTexImage2D(level)" );
  1819.       return;
  1820.    }
  1821.    if (border!=0 && border!=1) {
  1822.       gl_error( ctx, GL_INVALID_VALUE, "glCopyTexImage2D(border)" );
  1823.       return;
  1824.    }
  1825.    if (width<2*border || width>2+MAX_TEXTURE_SIZE || width<0) {
  1826.       gl_error( ctx, GL_INVALID_VALUE, "glCopyTexImage2D(width)" );
  1827.       return;
  1828.    }
  1829.    if (height<2*border || height>2+MAX_TEXTURE_SIZE || height<0) {
  1830.       gl_error( ctx, GL_INVALID_VALUE, "glCopyTexImage2D(height)" );
  1831.       return;
  1832.    }
  1833.    format = decode_internal_format( internalformat );
  1834.    if (format<0 || (internalformat>=1 && internalformat<=4)) {
  1835.       gl_error( ctx, GL_INVALID_VALUE, "glCopyTexImage2D(format)" );
  1836.       return;
  1837.    }
  1838.  
  1839.    teximage = gl_read_color_image( ctx, x, y, width, height, format );
  1840.    if (!teximage) {
  1841.       gl_error( ctx, GL_OUT_OF_MEMORY, "glCopyTexImage1D" );
  1842.       return;
  1843.    }
  1844.  
  1845.    gl_TexImage2D( ctx, target, level, internalformat, width, height,
  1846.                   border, GL_RGBA, GL_UNSIGNED_BYTE, teximage );
  1847.  
  1848.    gl_free_image( teximage );
  1849. }
  1850.  
  1851.  
  1852.  
  1853.  
  1854. /*
  1855.  * Do the work of glCopyTexSubImage[12]D.
  1856.  * TODO: apply pixel bias scale and mapping.
  1857.  */
  1858. static void copy_tex_sub_image( GLcontext *ctx, struct gl_texture_image *dest,
  1859.                                 GLint width, GLint height,
  1860.                                 GLint srcx, GLint srcy,
  1861.                                 GLint dstx, GLint dsty, GLint zoffset )
  1862. {
  1863.    GLint i, j;
  1864.    GLint format, components, rectarea;
  1865.  
  1866.    rectarea = width*height;
  1867.    zoffset *= rectarea; 
  1868.    format = dest->Format;
  1869.    components = components_in_intformat( format );
  1870.  
  1871.    for (j=0;j<height;j++) {
  1872.       GLubyte red[MAX_WIDTH], green[MAX_WIDTH];
  1873.       GLubyte blue[MAX_WIDTH], alpha[MAX_WIDTH];
  1874.       GLubyte *texptr;
  1875.  
  1876.       gl_read_color_span( ctx, width, srcx, srcy+j, red, green, blue, alpha );
  1877.  
  1878.       if (!ctx->Visual->EightBitColor) {
  1879.          /* scale red, green, blue, alpha values to range [0,255] */
  1880.          GLfloat rscale = 255.0f * ctx->Visual->InvRedScale;
  1881.          GLfloat gscale = 255.0f * ctx->Visual->InvGreenScale;
  1882.          GLfloat bscale = 255.0f * ctx->Visual->InvBlueScale;
  1883.          GLfloat ascale = 255.0f * ctx->Visual->InvAlphaScale;
  1884.          for (i=0;i<width;i++) {
  1885.             red[i]   = (GLubyte) (GLint) (red[i]   * rscale);
  1886.             green[i] = (GLubyte) (GLint) (green[i] * gscale);
  1887.             blue[i]  = (GLubyte) (GLint) (blue[i]  * bscale);
  1888.             alpha[i] = (GLubyte) (GLint) (alpha[i] * ascale);
  1889.          }
  1890.       }
  1891.  
  1892.       texptr = dest->Data + ( zoffset + (dsty+j) * width + dstx) * components;
  1893.  
  1894.       switch (format) {
  1895.          case GL_ALPHA:
  1896.             for (i=0;i<width;i++) {
  1897.                *texptr++ = alpha[i];
  1898.             }
  1899.             break;
  1900.          case GL_LUMINANCE:
  1901.             for (i=0;i<width;i++) {
  1902.                *texptr++ = red[i];
  1903.             }
  1904.             break;
  1905.          case GL_LUMINANCE_ALPHA:
  1906.             for (i=0;i<width;i++) {
  1907.                *texptr++ = red[i];
  1908.                *texptr++ = alpha[i];
  1909.             }
  1910.             break;
  1911.          case GL_INTENSITY:
  1912.             for (i=0;i<width;i++) {
  1913.                *texptr++ = red[i];
  1914.             }
  1915.             break;
  1916.          case GL_RGB:
  1917.             for (i=0;i<width;i++) {
  1918.                *texptr++ = red[i];
  1919.                *texptr++ = green[i];
  1920.                *texptr++ = blue[i];
  1921.             }
  1922.             break;
  1923.          case GL_RGBA:
  1924.             for (i=0;i<width;i++) {
  1925.                *texptr++ = red[i];
  1926.                *texptr++ = green[i];
  1927.                *texptr++ = blue[i];
  1928.                *texptr++ = alpha[i];
  1929.             }
  1930.             break;
  1931.       } /*switch*/
  1932.    } /*for*/         
  1933. }
  1934.  
  1935.  
  1936.  
  1937.  
  1938. void gl_CopyTexSubImage1D( GLcontext *ctx,
  1939.                               GLenum target, GLint level,
  1940.                               GLint xoffset, GLint x, GLint y, GLsizei width )
  1941. {
  1942.    struct gl_texture_image *teximage;
  1943.  
  1944.    if (INSIDE_BEGIN_END(ctx)) {
  1945.       gl_error( ctx, GL_INVALID_OPERATION, "glCopyTexSubImage1D" );
  1946.       return;
  1947.    }
  1948.    if (target!=GL_TEXTURE_1D) {
  1949.       gl_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage1D(target)" );
  1950.       return;
  1951.    }
  1952.    if (level<0 || level>=MAX_TEXTURE_LEVELS) {
  1953.       gl_error( ctx, GL_INVALID_VALUE, "glCopyTexSubImage1D(level)" );
  1954.       return;
  1955.    }
  1956.    if (width<0) {
  1957.       gl_error( ctx, GL_INVALID_VALUE, "glCopyTexSubImage1D(width)" );
  1958.       return;
  1959.    }
  1960.  
  1961.    teximage = ctx->Texture.Current1D->Image[level];
  1962.  
  1963.    if (teximage) {
  1964.       if (xoffset < -teximage->Border) {
  1965.          gl_error( ctx, GL_INVALID_VALUE, "glCopyTexSubImage1D(xoffset)" );
  1966.          return;
  1967.       }
  1968.       /* NOTE: we're adding the border here, not subtracting! */
  1969.       if (xoffset+width > teximage->Width+teximage->Border) {
  1970.          gl_error( ctx, GL_INVALID_VALUE,
  1971.                    "glCopyTexSubImage1D(xoffset+width)" );
  1972.          return;
  1973.       }
  1974.       if (teximage->Data) {
  1975.          copy_tex_sub_image( ctx, teximage, width, 1, x, y, xoffset, 0, 0 );
  1976.       }
  1977.    }
  1978.    else {
  1979.       gl_error( ctx, GL_INVALID_OPERATION, "glCopyTexSubImage1D" );
  1980.    }
  1981. }
  1982.  
  1983.  
  1984.  
  1985. void gl_CopyTexSubImage2D( GLcontext *ctx,
  1986.                               GLenum target, GLint level,
  1987.                               GLint xoffset, GLint yoffset,
  1988.                               GLint x, GLint y, GLsizei width, GLsizei height )
  1989. {
  1990.    struct gl_texture_image *teximage;
  1991.  
  1992.    if (INSIDE_BEGIN_END(ctx)) {
  1993.       gl_error( ctx, GL_INVALID_OPERATION, "glCopyTexSubImage2D" );
  1994.       return;
  1995.    }
  1996.    if (target!=GL_TEXTURE_2D) {
  1997.       gl_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage2D(target)" );
  1998.       return;
  1999.    }
  2000.    if (level<0 || level>=MAX_TEXTURE_LEVELS) {
  2001.       gl_error( ctx, GL_INVALID_VALUE, "glCopyTexSubImage2D(level)" );
  2002.       return;
  2003.    }
  2004.    if (width<0) {
  2005.       gl_error( ctx, GL_INVALID_VALUE, "glCopyTexSubImage2D(width)" );
  2006.       return;
  2007.    }
  2008.    if (height<0) {
  2009.       gl_error( ctx, GL_INVALID_VALUE, "glCopyTexSubImage2D(height)" );
  2010.       return;
  2011.    }
  2012.  
  2013.    teximage = ctx->Texture.Current2D->Image[level];
  2014.  
  2015.    if (teximage) {
  2016.       if (xoffset < -teximage->Border) {
  2017.          gl_error( ctx, GL_INVALID_VALUE, "glCopyTexSubImage2D(xoffset)" );
  2018.          return;
  2019.       }
  2020.       if (yoffset < -teximage->Border) {
  2021.          gl_error( ctx, GL_INVALID_VALUE, "glCopyTexSubImage2D(yoffset)" );
  2022.          return;
  2023.       }
  2024.       /* NOTE: we're adding the border here, not subtracting! */
  2025.       if (xoffset+width > teximage->Width+teximage->Border) {
  2026.          gl_error( ctx, GL_INVALID_VALUE,
  2027.                    "glCopyTexSubImage2D(xoffset+width)" );
  2028.          return;
  2029.       }
  2030.       if (yoffset+height > teximage->Height+teximage->Border) {
  2031.          gl_error( ctx, GL_INVALID_VALUE,
  2032.                    "glCopyTexSubImage2D(yoffset+height)" );
  2033.          return;
  2034.       }
  2035.  
  2036.       if (teximage->Data) {
  2037.          copy_tex_sub_image( ctx, teximage, width, height,
  2038.                              x, y, xoffset, yoffset, 0 );
  2039.       }
  2040.    }
  2041.    else {
  2042.       gl_error( ctx, GL_INVALID_OPERATION, "glCopyTexSubImage2D" );
  2043.    }
  2044. }
  2045.  
  2046.  
  2047.  
  2048. void gl_CopyTexSubImage3DEXT( GLcontext *ctx,
  2049.                               GLenum target, GLint level,
  2050.                               GLint xoffset, GLint yoffset, GLint zoffset,
  2051.                               GLint x, GLint y, GLsizei width, GLsizei height )
  2052. {
  2053.    struct gl_texture_image *teximage;
  2054.  
  2055.    if (INSIDE_BEGIN_END(ctx)) {
  2056.       gl_error( ctx, GL_INVALID_OPERATION, "glCopyTexSubImage3DEXT" );
  2057.       return;
  2058.    }
  2059.    if (target!=GL_TEXTURE_2D) {
  2060.       gl_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage3DEXT(target)" );
  2061.       return;
  2062.    }
  2063.    if (level<0 || level>=MAX_TEXTURE_LEVELS) {
  2064.       gl_error( ctx, GL_INVALID_VALUE, "glCopyTexSubImage3DEXT(level)" );
  2065.       return;
  2066.    }
  2067.    if (width<0) {
  2068.       gl_error( ctx, GL_INVALID_VALUE, "glCopyTexSubImage3DEXT(width)" );
  2069.       return;
  2070.    }
  2071.    if (height<0) {
  2072.       gl_error( ctx, GL_INVALID_VALUE, "glCopyTexSubImage3DEXT(height)" );
  2073.       return;
  2074.    }
  2075.  
  2076.    teximage = ctx->Texture.Current3D->Image[level];
  2077.    if (teximage) {
  2078.       if (xoffset < -teximage->Border) {
  2079.          gl_error( ctx, GL_INVALID_VALUE, "glCopyTexSubImage3DEXT(xoffset)" );
  2080.          return;
  2081.       }
  2082.       if (yoffset < -teximage->Border) {
  2083.          gl_error( ctx, GL_INVALID_VALUE, "glCopyTexSubImage3DEXT(yoffset)" );
  2084.          return;
  2085.       }
  2086.       if (zoffset < -teximage->Border) {
  2087.          gl_error( ctx, GL_INVALID_VALUE, "glCopyTexSubImage3DEXT(zoffset)" );
  2088.          return;
  2089.       }
  2090.       /* NOTE: we're adding the border here, not subtracting! */
  2091.       if (xoffset+width > teximage->Width+teximage->Border) {
  2092.          gl_error( ctx, GL_INVALID_VALUE,
  2093.                    "glCopyTexSubImage3DEXT(xoffset+width)" );
  2094.          return;
  2095.       }
  2096.       if (yoffset+height > teximage->Height+teximage->Border) {
  2097.          gl_error( ctx, GL_INVALID_VALUE,
  2098.                    "glCopyTexSubImage3DEXT(yoffset+height)" );
  2099.          return;
  2100.       }
  2101.       if (zoffset > teximage->Depth+teximage->Border) {
  2102.          gl_error( ctx, GL_INVALID_VALUE,
  2103.                    "glCopyTexSubImage3DEXT(zoffset+depth)" );
  2104.          return;
  2105.       }
  2106.  
  2107.       if (teximage->Data) {
  2108.          copy_tex_sub_image( ctx, teximage, width, height, 
  2109.                              x, y, xoffset, yoffset, zoffset);
  2110.       }
  2111.    }
  2112.    else {
  2113.       gl_error( ctx, GL_INVALID_OPERATION, "glCopyTexSubImage3DEXT" );
  2114.    }
  2115. }
  2116.  
  2117.